// UEXDataManager.cpp: implementation of the UEXDataManager class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "UEXDataManager.h"
#include <migrtion.h>
#include "UEEntityOperation.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

UEXDataManager::UEXDataManager(const CString& strHandle, BOOL bCreate, AcDbDatabase* pDB):
							   m_handle(strHandle)
{
	ASSERT(!strHandle.IsEmpty());
	ASSERT(!m_handle.isNull());
	if(pDB == NULL)
	{
		m_pDB = acdbCurDwg();
	}
	else
	{
		m_pDB = pDB;
	}
	m_bCreate = bCreate;
}

UEXDataManager::UEXDataManager(const AcDbHandle& handle, BOOL bCreate, AcDbDatabase* pDB)
{
	ASSERT(!handle.isNull());
	m_handle = handle;
	if(pDB == NULL)
	{
		m_pDB = acdbCurDwg();
	}
	else
	{
		m_pDB = pDB;
	}
	m_bCreate = bCreate;
}
UEXDataManager::~UEXDataManager()
{

}

UEXData* UEXDataManager::GetUEXData(const CString& strName)
{
	UEXData* pXData = NULL;
	pXData = GetManaged(strName);
	if(m_bCreate && pXData == NULL)
		return NewUEXData(strName);
	return pXData;
}

UEXData* UEXDataManager::NewUEXData(const CString& strName)
{
	UEXData* pXData = NULL;
	pXData = new UEXData(strName);
	ASSERT(pXData);
	this->Add(strName, pXData);
	return pXData;
}

BOOL UEXDataManager::ReadUEXData()
{
	AcDbObject* pObject = CUEEntityOperation::OpenEntityRead(m_handle);
	if(pObject == NULL)
	{
		ASSERT(FALSE);
		return FALSE;
	}

	struct resbuf* pRb = NULL;
	pRb = pObject->xData();
	pObject->close();
	if(pRb == NULL)
		return FALSE;

	return ParseResbuf(pRb);
}

BOOL UEXDataManager::ParseResbuf(struct resbuf* pRb)
{
	UEXData* pXData = NULL;
	struct resbuf* pTempRb = pRb;
	while(pRb != NULL)
	{
		if(pRb->restype == 1001)
		{
			pXData = new UEXData(CString(pRb->resval.rstring));
			this->Add(CString(pRb->resval.rstring), pXData);
			pRb = pRb->rbnext;
			continue;
		}
		ASSERT(pXData);
		pXData->Add(pRb);
		pRb = pRb->rbnext;
	}

	acutRelRb(pTempRb);
	return TRUE;
}

BOOL UEXDataManager::WriteUEXData()
{
	CArray<resbuf*, resbuf*> pos;
	resbuf* pBuf = NULL;
	pBuf = ConstructResList(pos);

	AcDbObject* pObject = CUEEntityOperation::OpenObjectWrite(m_handle);
	if(pObject == NULL)
	{
		ASSERT(FALSE);
		return FALSE;
	}

	struct resbuf* pRb = NULL;
	Acad::ErrorStatus es = pObject->setXData(pBuf);
	pObject->close();
	if(es != Acad::eOk)
		return FALSE;

	ExtractResList(pos);
	return TRUE;
}

resbuf* UEXDataManager::ConstructResList(CArray<resbuf*, resbuf*>& pos)
{
	resbuf* pStart = NULL;
	resbuf* pEnd = NULL;
	UEXData* pData = NULL;
	Iterator* pIterator = NewIterator();
	pIterator->Begin();
	pData = pIterator->Get();
	ASSERT(pData);
	acdbRegApp(pData->Name());
	pStart = (resbuf*)pData->FirstBuf();
	pEnd = (resbuf*)pData->LastBuf();
	pos.Add(pEnd);
	pIterator->Next();
	
	for(; !pIterator->End(); pIterator->Next())
	{
		ASSERT(pIterator->Get());
		pData = pIterator->Get();
		acdbRegApp(pData->Name());
		pEnd->rbnext = (resbuf*)pData->FirstBuf();
		pEnd = (resbuf*)pData->LastBuf();
		pos.Add(pEnd);
	}
	delete pIterator;

	return pStart;
}

void UEXDataManager::ExtractResList(const CArray<resbuf*, resbuf*>& pos)
{
	for(int i = 0; i < pos.GetSize(); i++)
	{
		resbuf* pBuf = pos.GetAt(i);
		ASSERT(pBuf);
		pBuf->rbnext = NULL;
	}
}